//	global variables
var selectedPropertyNames = new Array();	//	store all the names of selected properties
var selectedProperty = new Array();			//	store all the information of the selected properties
var queryConditionsJSONString = "";			//	store all the selected condition properties
var selectedConditionNames = new Array();	//	store all the selected condition properties names
var queryConditions = new Array();			//	store info about query form

var rankScores = new Array();

//	set recommendation type, 1 indicate baseline, 2 indicate makimum likelihood
var recommendationConditionType = 2;
var recommendationFilterType = 2;



/**
 * onready
 */
$(function(){
	var content = "before";
	$.getJSON("init.action",
	null,
	function(data){
		//	init queryform
		initSubmitButton();
		initResetButton();
		
		$("#queryform").append("<table width='600' border=1 align='center'><tr><th>property</th><th>condition</th><th>value</th><th>operation</th></tr></table>");
		
		//	init queryresult
		$("#queryresult").append("Click header to remove column");
		$("#queryresult").append("<table border=1 align='center'></table>");
		
		//	init propertylist
		$("#propertylist").append("<table border=0 width=280>");
		$.each(data.properties, function(index, property){
			$("#propertylist").append("<tr id='property'><td id='name'>" + property + "</td><td width=50>select</td></tr>");
		});		
		$("#propertylist").append("</table>");
		
		//	init conditionlist
		$("#conditionlist").append("<table border=0 width=280>");
		$("conditionlist").append("</table>");
		
		//	add click event to 'select'
		$.each($("tr#property"), function(n, value){
			var text = $(this).children().filter('#name').text();
			
			$(this).children().filter(":contains('select')").bind('click', function(event){
				selectedPropertyNames.push(text);
				updateResultFormHeader();
			}).css('cursor', 'pointer');
		});
	});
});

/**
 * When the user choose a filter property, then the result form header should be updated.
 */
function updateResultFormHeader(){
	$("#queryresult table").html("");
	$("#queryresult table").append("<tr id='header'>");
	$.each(selectedPropertyNames, function(n, value){
		$("#queryresult tr").append("<th width='30'>" + value + "</th>");
	});
	
	$.each($("#queryresult th"), function(n, value){
		$(this).bind('click', function(event){
			removeProperty(n);
		}).css('cursor', 'pointer');
	});
	
	$("#queryresult table").append("</tr>");
	updateCondition();
	updateFilter();
}

function removeProperty(index){
	selectedPropertyNames.splice(index, 1);	//	remove the selected property according to which header is removed
	updateResultFormHeader();	//	redraw header according to selected property list
}

function initSubmitButton(){
	$("#submit").bind('click', function(event){
		var querystring = "";
		var filterstring = selectedPropertyNames.join(',');
		var conditions = $("select");
		var values = $("input[type='text']");
		$.each(selectedConditionNames, function(n, value){
			var selectedIndex = conditions[n].selectedIndex;
			querystring += value 
						+ conditions[n][selectedIndex].text 
						+ $(values[n]).val() + ",";
		});
		
		querystring = querystring.substring(0, querystring.length - 1);
		$.getJSON("query.action", 
			{queryConditionString: querystring, filterString: filterstring},
			function(data){
				var result = data.queryResult;
				initResult(result);
		});
	});
}

function initResetButton(){
	//	empty all the sotrages
	$("#reset").bind('click', function(event){
		selectedPropertyNames = new Array();	
		selectedProperty = new Array();			
		queryConditionsJSONString = "";			
		selectedConditionNames = new Array();	
		queryConditions = new Array();	
		rankScores = new Array();
		document.location.reload();
	});
}

function initResult(result){
	updateResultFormHeader();
	for(var i = 0; i < result.length; ++i){
		var record = result[i];
		record = eval("(" + record + ")");
		var line = "<tr>";
		$.each(selectedPropertyNames, function(n, value){
			line += "<td>" + record[value] + "</td>";
		});
		line += "</tr>";
		$("#queryresult table").append(line);
	}
}

function updateCondition(){
	if(recommendationConditionType == 1){
		updateConditionBaseline();
	} else if(recommendationConditionType == 2){
		updateConditionMaximumLikelihood();
	}
	
}

function updateConditionMaximumLikelihood(){
	var conditions = selectedConditionNames.join(",");
	var properties = selectedPropertyNames.join(",");
	$.getJSON("updateCondition.action", 
		{filterString: properties, queryConditions: queryConditionsJSONString},
		function(data){
			$("#conditionlist table").html("");
			
			rankScores = new Array();
			//	add recommended conditions
			$.each(data.recommendedConditions, function(index, condition){
				rankScores.push(condition);
//				$("#conditionlist table").append("<tr id='reommendcondition'><td id='name'>" + condition['name'] + "</td><td>select</td></tr>");
			});
			
			
			//	bubble sort the conditions according to the score
			for(var i = 0; i < rankScores.length; ++i){
				for(var j = rankScores.length - 1; j > i; --j){
					if(rankScores[j]['score'] > rankScores[j - 1]['score']){
						var tmpName = rankScores[j]['name'].toString();
						var tmpScore = rankScores[j]['score'];
						
						rankScores[j]['name'] = rankScores[j - 1]['name'].toString();
						rankScores[j]['score'] = rankScores[j - 1]['score'];
						
						rankScores[j - 1]['name'] = tmpName;
						rankScores[j - 1]['score'] = tmpScore;
					}
				}
			}
			
			for(var i = 0; i < rankScores.length; ++i){
				$("#conditionlist table").append("<tr id='reommendcondition'><td id='name'>" + rankScores[i]['name'] + "</td><td>select</td></tr>");
			}
			
			//	add click event to conditions
			$.each($("tr#reommendcondition"), function(n, value){
				var text = $(this).children().filter("#name").text();
				$(this).children().filter(":contains('select')").bind('click', function(event){
					selectedConditionNames.push(text);
					updateQueryForm(text, "add");
				}).css('cursor', 'pointer');
			});
		}
	);
}

function updateConditionBaseline(){
	var conditions = selectedConditionNames.join(",");
	var properties = selectedPropertyNames.join(",");
	$.getJSON("updateCondition.action", 
		{filterString: properties, queryConditions: queryConditionsJSONString},
		function(data){
			$("#conditionlist table").html("");
			//	add recommended conditions
			$.each(data.recommendedConditions, function(index, condition){
				$("#conditionlist table").append("<tr id='reommendcondition'><td id='name'>" + condition['name'] + "</td><td>select</td></tr>");
			});
			//	add click event to conditions
			$.each($("tr#reommendcondition"), function(n, value){
				var text = $(this).children().filter("#name").text();
				$(this).children().filter(":contains('select')").bind('click', function(event){
					selectedConditionNames.push(text);
					updateQueryForm(text, "add");
				}).css('cursor', 'pointer');
			});
		}
	);
}

function updateFilter(){
	if(recommendationFilterType == 1){
		updateFilterBaseline();
	}else if(recommendationFilterType == 2){
		updateFilterMaximumLikelihood();
	}
}

function updateFilterBaseline(){
	//	the baseline of recommendate filter components is just let it be
}

function updateFilterMaximumLikelihood(){
	var conditions = selectedConditionNames.join(",");
	var properties = selectedPropertyNames.join(",");
	$.getJSON("updateFilter.action", 
		{filterString: properties, queryConditions: queryConditionsJSONString},
		function(data){
			rankScores = new Array();
			//	add recommended conditions
			$.each(data.recommendedFilters, function(index, condition){
				rankScores.push(condition);
//				$("#conditionlist table").append("<tr id='reommendcondition'><td id='name'>" + condition['name'] + "</td><td>select</td></tr>");
			});
			
			
			//	bubble sort the conditions according to the score
			for(var i = 0; i < rankScores.length; ++i){
				for(var j = rankScores.length - 1; j > i; --j){
					if(rankScores[j]['score'] > rankScores[j - 1]['score']){
						var tmpName = rankScores[j]['name'].toString();
						var tmpScore = rankScores[j]['score'];
						
						rankScores[j]['name'] = rankScores[j - 1]['name'].toString();
						rankScores[j]['score'] = rankScores[j - 1]['score'];
						
						rankScores[j - 1]['name'] = tmpName;
						rankScores[j - 1]['score'] = tmpScore;
					}
				}
			}
			
			//	update pages
			$("#propertylist").html("");
			$("#propertylist").append("<table border=0 width=280>");
			$.each(rankScores, function(index, property){
				$("#propertylist").append("<tr id='property'><td id='name'>" + property['name'] + "</td><td width=50>select</td></tr>");
			});		
			$("#propertylist").append("</table>");
			
			//	add click event to 'select'
			$.each($("tr#property"), function(n, value){
				var text = $(this).children().filter('#name').text();
				
				$(this).children().filter(":contains('select')").bind('click', function(event){
					selectedPropertyNames.push(text);
					updateResultFormHeader();
				}).css('cursor', 'pointer');
			});
		}
	);

}

function updateQueryForm(condName, operation){
	
	//	store previous column
	var qCond = $("tr#querycondition");
	queryConditions = new Array();
	$.each(qCond, function(n, value){
		queryConditionsJSONString += "{";
		var conditionName = $(this).children().filter("#queryconditionproperty").text();
		var conditionOperator = $(this).children().filter("#condition").children().filter("select").children().filter(":selected").text();
		var conditionValue = $(this).children().filter("#value").children().filter(":text").attr("value");
		
		var queryCondition = new Object();
		queryCondition.name = conditionName;
		queryCondition.operator = conditionOperator;
		queryCondition.value = conditionValue;
		queryConditions.push(queryCondition);
	});
	
	//	empty table
	$("#queryform table").html("");
	$("#queryform table").append("<tr><th>property</th><th>condition</th><th>value</th><th>operation</th></tr>");

	//	restore previous column
	$.each(queryConditions, function(n, condition){
		var selectStr;
		if(condition.operator == '='){
			selectStr = "<td id='condition'><select>"
				+ "<option selected='true' value='='>=</option>"
				+ "<option value='<>'><></option>"
				+ "<option value='<'><</option>"
				+ "<option value='>'>></option>"
				+ "<option value='<='><=</option>"
				+ "<option value='>='>>=</option>"
				+ "</select></td>";
		}
		else if(condition.operator == '<>'){
			selectStr = "<td id='condition'><select>"
				+ "<option value='='>=</option>"
				+ "<option selected='true' value='<>'><></option>"
				+ "<option value='<'><</option>"
				+ "<option value='>'>></option>"
				+ "<option value='<='><=</option>"
				+ "<option value='>='>>=</option>"
				+ "</select></td>";
		}
		else if(condition.operator == '<'){
			selectStr = "<td id='condition'><select>"
				+ "<option value='='>=</option>"
				+ "<option value='<>'><></option>"
				+ "<option selected='true' value='<'><</option>"
				+ "<option value='>'>></option>"
				+ "<option value='<='><=</option>"
				+ "<option value='>='>>=</option>"
				+ "</select></td>";
		}
		else if(condition.operator == '>'){
		 	selectStr = "<td id='condition'><select>"
				+ "<option value='='>=</option>"
				+ "<option value='<>'><></option>"
				+ "<option value='<'><</option>"
				+ "<option selected='true' value='>'>></option>"
				+ "<option value='<='><=</option>"
				+ "<option value='>='>>=</option>"
				+ "</select></td>";
		}
		else if(condition.operator == '<='){
		 	selectStr = "<td id='condition'><select>"
				+ "<option value='='>=</option>"
				+ "<option value='<>'><></option>"
				+ "<option value='<'><</option>"
				+ "<option value='>'>></option>"
				+ "<option selected='true' value='<='><=</option>"
				+ "<option value='>='>>=</option>"
				+ "</select></td>";
		}
		else if(condition.operator == '>='){
			selectStr = "<td id='condition'><select>"
				+ "<option value='='>=</option>"
				+ "<option value='<>'><></option>"
				+ "<option value='<'><</option>"
				+ "<option value='>'>></option>"
				+ "<option value='<='><=</option>"
				+ "<option selected='true' value='>='>>=</option>"
				+ "</select></td>";
		}
		if(operation == "add" || (operation == "delete" && condName != condition.name)){
			$("#queryform table").append("<tr id='querycondition'><td id='queryconditionproperty'>" + condition.name + "</td>"
				+ selectStr
				+ "<td id='value'><input type='text' value='" + condition.value + "'/></td>"
				+ "<td>delete</td></tr>");
		}
	});
	
	//	add new column
	if(operation == "add"){
		$("#queryform table").append("<tr id='querycondition'><td id='queryconditionproperty'>" + condName + "</td>"
			+ "<td id='condition'><select>"
			+ "<option selected='true' value='='>=</option>"
			+ "<option value='<>'><></option>"
			+ "<option value='<'><</option>"
			+ "<option value='>'>></option>"
			+ "<option value='<='><=</option>"
			+ "<option value='>='>>=</option>"
			+ "</select></td>"
			+ "<td id='value'><input type='text' value='0'/></td>"
			+ "<td>delete</td></tr>");
		var queryCondition = new Object();
		queryCondition.name = condName;
		queryCondition.operator = '=';
		queryCondition.value = 0;
		queryConditions.push(queryCondition);
	}
	
	$.each($("#queryform td").filter(":contains('delete')"), function(n, value){
		$(this).bind('click', function(event){
			removeCondition(n);
		}).css('cursor', 'pointer');
	});
	
	//	generate queryConditionJSON
	queryConditionsJSONString = "[";
	var qCond = $("tr#querycondition");
	queryConditions = new Array();
	$.each(qCond, function(n, value){
		queryConditionsJSONString += "{";
		var conditionName = $(this).children().filter("#queryconditionproperty").text();
		var conditionOperator = $(this).children().filter("#condition").children().filter("select").children().filter(":selected").text();
		var conditionValue = $(this).children().filter("#value").children().filter(":text").attr("value");
		queryConditionsJSONString += "\"name\":\"" + conditionName + "\", \"operator\":\"" 
						+ conditionOperator + "\", \"value\":\"" + conditionValue + "\"";
		queryConditionsJSONString += "},";
		
		var queryCondition = new Object();
		queryCondition.name = conditionName;
		queryCondition.operator = conditionOperator;
		queryCondition.value = conditionValue;
		queryConditions.push(queryCondition);
	});
	queryConditionsJSONString = queryConditionsJSONString.substring(0, queryConditionsJSONString.length - 1);
	queryConditionsJSONString += "]";
	if(qCond.size() == 0){
		queryConditionsJSONString = "";
	}
	
	updateCondition();
	updateFilter();
}

function removeCondition(index){
	var condName = selectedConditionNames[index];
	selectedConditionNames.splice(index, 1);
	queryConditions.splice(index, 1);
	updateQueryForm(condName, "delete");
	updateCondition();
}